Reactãšã©ãŒå¢çããã¹ã¿ãŒããŠãå埩åããããŠãŒã¶ãŒãã¬ã³ããªãŒãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããŸãããããã¹ããã©ã¯ãã£ã¹ãå®è£ ãã¯ããã¯ãé«åºŠãªãšã©ãŒåŠçæŠç¥ãåŠã³ãŸãã
Reactãšã©ãŒå¢çïŒå ç¢ãªã¢ããªã±ãŒã·ã§ã³ã®ããã®åªé ãªãšã©ãŒåŠçãã¯ããã¯
Webéçºã®ãã€ãããã¯ãªäžçã§ã¯ãå ç¢ã§ãŠãŒã¶ãŒãã¬ã³ããªãŒãªã¢ããªã±ãŒã·ã§ã³ãäœæããããšãæãéèŠã§ããReactã¯ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããã®äžè¬çãªJavaScriptã©ã€ãã©ãªã§ããããšã©ãŒãåªé ã«åŠçããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸããããããšã©ãŒå¢çã§ãããã®å æ¬çãªã¬ã€ãã§ã¯ããšã©ãŒå¢çã®æŠå¿µãæãäžãããã®ç®çãå®è£ ãããã³å埩åã®ããReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ãã¹ããã©ã¯ãã£ã¹ãæ¢ããŸãã
ãšã©ãŒå¢çã®å¿ èŠæ§ãçè§£ãã
Reactã³ã³ããŒãã³ãã¯ãä»ã®ã³ãŒããšåæ§ã«ããšã©ãŒã®åœ±é¿ãåãããããã®ã§ãããããã®ãšã©ãŒã¯ã次ã®ãããªããŸããŸãªãœãŒã¹ããçºçããå¯èœæ§ããããŸãã
- äºæããªãããŒã¿ïŒã³ã³ããŒãã³ããäºæããªã圢åŒã§ããŒã¿ãåãåããã¬ã³ããªã³ã°ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸãã
- ããžãã¯ãšã©ãŒïŒã³ã³ããŒãã³ãã®ããžãã¯ã®ãã°ã¯ãäºæããªãåäœããšã©ãŒãåŒãèµ·ããå¯èœæ§ããããŸãã
- å€éšäŸåé¢ä¿ïŒå€éšã©ã€ãã©ãªãŸãã¯APIã®åé¡ããã³ã³ããŒãã³ãã«ãšã©ãŒãäŒæãããå¯èœæ§ããããŸãã
é©åãªãšã©ãŒåŠçããªããšãReactã³ã³ããŒãã³ãã®ãšã©ãŒãã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãäœäžããå¯èœæ§ããããŸãããšã©ãŒå¢çã¯ããããã®ãšã©ãŒããã£ããããã³ã³ããŒãã³ãããªãŒã«äŒæããã®ãé²ãæ¹æ³ãæäŸããåã ã®ã³ã³ããŒãã³ãã倱æããå Žåã§ãã¢ããªã±ãŒã·ã§ã³ãæ©èœãç¶ããããã«ããŸãã
Reactãšã©ãŒå¢çãšã¯ïŒ
ãšã©ãŒå¢çã¯ãåã³ã³ããŒãã³ãããªãŒå ã®JavaScriptãšã©ãŒããã£ãããããããã®ãšã©ãŒããã°ã«èšé²ããã¯ã©ãã·ã¥ããã³ã³ããŒãã³ãããªãŒã®ä»£ããã«ãã©ãŒã«ããã¯UIã衚瀺ããReactã³ã³ããŒãã³ãã§ãããããã¯ããšã©ãŒãã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ãããã®ãé²ãå®å šããããšããŠæ©èœããŸãã
ãšã©ãŒå¢çã®äž»ãªç¹åŸŽïŒ
- ã¯ã©ã¹ã³ã³ããŒãã³ãã®ã¿ïŒãšã©ãŒå¢çã¯ãã¯ã©ã¹ã³ã³ããŒãã³ããšããŠå®è£ ããå¿ èŠããããŸãã颿°ã³ã³ããŒãã³ããšããã¯ã䜿çšããŠãšã©ãŒå¢çãäœæããããšã¯ã§ããŸããã
- ã©ã€ããµã€ã¯ã«ã¡ãœããïŒç¹å®ã©ã€ããµã€ã¯ã«ã¡ãœããã§ãã
static getDerivedStateFromError()ããã³componentDidCatch()ã䜿çšããŠããšã©ãŒãåŠçããŸãã - ããŒã«ã«ãšã©ãŒåŠçïŒãšã©ãŒå¢çã¯ãåã³ã³ããŒãã³ãã®ãšã©ãŒã®ã¿ããã£ããããããèªäœã§ã¯ãšã©ãŒããã£ããããŸããã
ãšã©ãŒå¢çã®å®è£
åºæ¬çãªãšã©ãŒå¢çã³ã³ããŒãã³ããäœæããããã»ã¹ãèŠãŠã¿ãŸãããïŒ
1. ãšã©ãŒå¢çã³ã³ããŒãã³ãã®äœæ
ãŸããããšãã°ErrorBoundaryãšããååã®æ°ããã¯ã©ã¹ã³ã³ããŒãã³ããäœæããŸãïŒ
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return {
hasError: true
};
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error("Caught error: ", error, errorInfo);
// Example: logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return (
<div>
<h2>åé¡ãçºçããŸããã</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
説æïŒ
- ã³ã³ã¹ãã©ã¯ã¿ïŒ
hasErrorïŒfalseã§ã³ã³ããŒãã³ãã®ç¶æ ãåæåããŸãã static getDerivedStateFromError(error)ïŒãã®ã©ã€ããµã€ã¯ã«ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã«ãã£ãŠãšã©ãŒãã¹ããŒãããåŸã«åŒã³åºãããŸãããšã©ãŒãåŒæ°ãšããŠåä¿¡ããã³ã³ããŒãã³ãã®ç¶æ ãæŽæ°ã§ããŸããããã§ã¯ãhasErrorãtrueã«èšå®ããŠããã©ãŒã«ããã¯UIãããªã¬ãŒããŸããããã¯staticã¡ãœããã§ããããã颿°å ã§thisã䜿çšã§ããŸãããcomponentDidCatch(error, errorInfo)ïŒãã®ã©ã€ããµã€ã¯ã«ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã«ãã£ãŠãšã©ãŒãã¹ããŒãããåŸã«åŒã³åºãããŸãã2ã€ã®åŒæ°ãåãåããŸããerrorïŒã¹ããŒããããšã©ãŒãerrorInfoïŒãšã©ãŒãçºçããã³ã³ããŒãã³ãã¹ã¿ãã¯ã«é¢ããæ å ±ãå«ããªããžã§ã¯ããããã¯ãããã°ã«éåžžã«åœ¹ç«ã¡ãŸãã
ãã®ã¡ãœããå ãããSentryãRollbarããŸãã¯ã«ã¹ã¿ã ãã®ã³ã°ãœãªã¥ãŒã·ã§ã³ãªã©ã®ãµãŒãã¹ã«ãšã©ãŒãèšé²ã§ããŸãããã®é¢æ°å ã§ãšã©ãŒãåã¬ã³ããªã³ã°ãŸãã¯ä¿®æ£ããããšããããšã¯é¿ããŠãã ããããã®äž»ãªç®çã¯ãåé¡ãèšé²ããããšã§ãã
render()ïŒrenderã¡ãœããã¯ãhasErrorç¶æ ã確èªããŸããtrueã®å Žåããã©ãŒã«ããã¯UIïŒãã®å Žåã¯ãåçŽãªãšã©ãŒã¡ãã»ãŒãžïŒãã¬ã³ããªã³ã°ããŸãããã以å€ã®å Žåã¯ãã³ã³ããŒãã³ãã®åãã¬ã³ããªã³ã°ããŸãã
2. ãšã©ãŒå¢çã®äœ¿çš
ãšã©ãŒå¢çã䜿çšããã«ã¯ããšã©ãŒãã¹ããŒããå¯èœæ§ã®ããã³ã³ããŒãã³ããErrorBoundaryã³ã³ããŒãã³ãã§ã©ããããã ãã§ãïŒ
import ErrorBoundary from './ErrorBoundary';
function MyComponent() {
// This component might throw an error
return (
<ErrorBoundary>
<PotentiallyBreakingComponent />
</ErrorBoundary>
);
}
export default MyComponent;
PotentiallyBreakingComponentããšã©ãŒãã¹ããŒãããšãErrorBoundaryã¯ããããã£ãããããšã©ãŒããã°ã«èšé²ãããã©ãŒã«ããã¯UIãã¬ã³ããªã³ã°ããŸãã
3. ã°ããŒãã«ã³ã³ããã¹ãã䜿çšãã説æçãªäŸ
ãªã¢ãŒããµãŒããŒãããã§ããããã補åæ
å ±ã衚瀺ããeã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãèããŠã¿ãŸããããã³ã³ããŒãã³ãProductDisplayã¯ã補åã®è©³çްãã¬ã³ããªã³ã°ãã圹å²ãæ
ã£ãŠããŸãããã ãããµãŒããŒãäºæããªãããŒã¿ãè¿ãããšããããã¬ã³ããªã³ã°ãšã©ãŒã«ã€ãªããå¯èœæ§ããããŸãã
// ProductDisplay.js
import React from 'react';
function ProductDisplay({ product }) {
// Simulate a potential error if product.price is not a number
if (typeof product.price !== 'number') {
throw new Error('Invalid product price');
}
return (
<div>
<h2>{product.name}</h2>
<p>Price: {product.price}</p>
<img src={product.imageUrl} alt={product.name} />
</div>
);
}
export default ProductDisplay;
ãã®ãããªãšã©ãŒããä¿è·ããã«ã¯ãProductDisplayã³ã³ããŒãã³ããErrorBoundaryã§ã©ããããŸãïŒ
// App.js
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
import ProductDisplay from './ProductDisplay';
function App() {
const product = {
name: 'Example Product',
price: 'Not a Number', // Intentionally incorrect data
imageUrl: 'https://example.com/image.jpg'
};
return (
<div>
<ErrorBoundary>
<ProductDisplay product={product} />
</ErrorBoundary>
</div>
);
}
export default App;
ãã®ã·ããªãªã§ã¯ãproduct.priceãæå³çã«æ°å€ã§ã¯ãªãæååã«èšå®ãããŠãããããProductDisplayã³ã³ããŒãã³ãã¯ãšã©ãŒãã¹ããŒããŸããErrorBoundaryã¯ãã®ãšã©ãŒããã£ããããã¢ããªã±ãŒã·ã§ã³å
šäœãã¯ã©ãã·ã¥ããã®ãé²ããç ŽæããProductDisplayã³ã³ããŒãã³ãã®ä»£ããã«ãã©ãŒã«ããã¯UIã衚瀺ããŸãã
4. åœéåãããã¢ããªã±ãŒã·ã§ã³ã®ãšã©ãŒå¢ç
ã°ããŒãã«ãªãŒãã£ãšã³ã¹åãã®ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå ŽåããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžãããããã«ããšã©ãŒã¡ãã»ãŒãžãããŒã«ã©ã€ãºããå¿ èŠããããŸãããšã©ãŒå¢çã¯ãåœéåïŒi18nïŒã©ã€ãã©ãªãšçµã¿åãããŠäœ¿çšããŠã翻蚳ããããšã©ãŒã¡ãã»ãŒãžã衚瀺ã§ããŸãã
// ErrorBoundary.js (with i18n support)
import React from 'react';
import { useTranslation } from 'react-i18next'; // Assuming you're using react-i18next
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null,
};
}
static getDerivedStateFromError(error) {
return {
hasError: true,
error: error,
};
}
componentDidCatch(error, errorInfo) {
console.error("Caught error: ", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
return (
<FallbackUI error={this.state.error} errorInfo={this.state.errorInfo}/>
);
}
return this.props.children;
}
}
const FallbackUI = ({error, errorInfo}) => {
const { t } = useTranslation();
return (
<div>
<h2>{t('error.title')}</h2>
<p>{t('error.message')}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{error && error.toString()}<br />
{errorInfo?.componentStack}
</details>
</div>
);
}
export default ErrorBoundary;
ãã®äŸã§ã¯ãreact-i18nextã䜿çšããŠããã©ãŒã«ããã¯UIã®ãšã©ãŒã¿ã€ãã«ãšã¡ãã»ãŒãžã翻蚳ããŸããt('error.title')颿°ãšt('error.message')颿°ã¯ããŠãŒã¶ãŒãéžæããèšèªã«åºã¥ããŠé©åãªç¿»èš³ãååŸããŸãã
5. ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒã®èæ ®äºé
ãµãŒããŒãµã€ãã§ã¬ã³ããªã³ã°ãããã¢ããªã±ãŒã·ã§ã³ã§ãšã©ãŒå¢çã䜿çšããå ŽåããµãŒããŒãã¯ã©ãã·ã¥ããªãããã«ããšã©ãŒãé©åã«åŠçããããšãéèŠã§ããReactã®ããã¥ã¡ã³ãã§ã¯ããµãŒããŒäžã§ã¬ã³ããªã³ã°ãšã©ãŒããå埩ããããã«ãšã©ãŒå¢çã䜿çšããããšãé¿ããããšãæšå¥šããŠããŸãã代ããã«ãã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããåã«ãšã©ãŒãåŠçãããããµãŒããŒäžã«éçãªãšã©ãŒããŒãžãã¬ã³ããªã³ã°ããŸãã
ãšã©ãŒå¢çã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹
- ç²åºŠã®é«ãã³ã³ããŒãã³ããã©ããããïŒã¢ããªã±ãŒã·ã§ã³ã®åã ã®ã³ã³ããŒãã³ããŸãã¯å°ããªã»ã¯ã·ã§ã³ããšã©ãŒå¢çã§ã©ããããŸããããã«ããã1ã€ã®ãšã©ãŒãUIå šäœãã¯ã©ãã·ã¥ãããã®ãé²ããŸããã¢ããªã±ãŒã·ã§ã³å šäœã§ã¯ãªããç¹å®ã®æ©èœãŸãã¯ã¢ãžã¥ãŒã«ãã©ããããããšãæ€èšããŠãã ããã
- ãšã©ãŒããã°ã«èšé²ããïŒ
componentDidCatch()ã¡ãœããã䜿çšããŠããšã©ãŒãç£èŠãµãŒãã¹ã«èšé²ããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®åé¡ã远跡ããã³ä¿®æ£ã§ããŸããSentryãRollbarãBugsnagãªã©ã®ãµãŒãã¹ã¯ããšã©ãŒã®è¿œè·¡ãšã¬ããŒãã«äžè¬çã«äœ¿çšãããŠããŸãã - æçãªãã©ãŒã«ããã¯UIãæäŸããïŒãã©ãŒã«ããã¯UIã«ãŠãŒã¶ãŒãã¬ã³ããªãŒãªãšã©ãŒã¡ãã»ãŒãžã衚瀺ããŸããå°éçšèªãé¿ããç¶è¡æ¹æ³ã«é¢ããæç€ºãæäŸããŸãïŒäŸïŒããŒãžãæŽæ°ããããµããŒãã«é£çµ¡ããïŒãå¯èœã§ããã°ããŠãŒã¶ãŒãå®è¡ã§ãã代æ¿ã¢ã¯ã·ã§ã³ãææ¡ããŸãã
- éå°ã«äœ¿çšããªãïŒãã¹ãŠã®ã³ã³ããŒãã³ãããšã©ãŒå¢çã§ã©ããããããšã¯é¿ããŠãã ãããå€éšAPIããããŒã¿ããã§ããããããè€éãªãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåŠçãããããã³ã³ããŒãã³ããªã©ããšã©ãŒãçºçããããé åã«çŠç¹ãåœãŠãŸãã
- ãšã©ãŒå¢çããã¹ãããïŒã©ããããã³ã³ããŒãã³ãã§æå³çã«ãšã©ãŒãã¹ããŒããŠããšã©ãŒå¢çãæ£ããæ©èœããŠããããšã確èªããŸãããŠããããã¹ããŸãã¯çµ±åãã¹ããäœæããŠããã©ãŒã«ããã¯UIãæåŸ ã©ããã«è¡šç€ºããããšã©ãŒãæ£ãããã°ã«èšé²ãããããšã確èªããŸãã
- ãšã©ãŒå¢çã¯ä»¥äžã«ã¯äœ¿çšã§ããŸããïŒ
- ã€ãã³ããã³ãã©ãŒ
- éåæã³ãŒãïŒäŸïŒ
setTimeoutãŸãã¯requestAnimationFrameã³ãŒã«ããã¯ïŒ - ãµãŒããŒãµã€ãã¬ã³ããªã³ã°
- ãšã©ãŒå¢çèªäœã§ã¹ããŒããããšã©ãŒïŒåã§ã¯ãªãïŒ
é«åºŠãªãšã©ãŒåŠçæŠç¥
1. å詊è¡ã¡ã«ããºã
å Žåã«ãã£ãŠã¯ããšã©ãŒã®åå ãšãªã£ãæäœãå詊è¡ããããšã§ããšã©ãŒããå埩ã§ããå ŽåããããŸããããšãã°ããããã¯ãŒã¯ãªã¯ãšã¹ãã倱æããå Žåãçãé å»¶åŸã«å詊è¡ã§ããŸãããšã©ãŒå¢çãå詊è¡ã¡ã«ããºã ãšçµã¿åãããŠãããå埩åã®ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸã§ããŸãã
// ErrorBoundaryWithRetry.js
import React from 'react';
class ErrorBoundaryWithRetry extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
retryCount: 0,
};
}
static getDerivedStateFromError(error) {
return {
hasError: true,
};
}
componentDidCatch(error, errorInfo) {
console.error("Caught error: ", error, errorInfo);
}
handleRetry = () => {
this.setState(prevState => ({
hasError: false,
retryCount: prevState.retryCount + 1,
}), () => {
// This forces the component to re-render. Consider better patterns with controlled props.
this.forceUpdate(); // WARNING: Use with caution
if (this.props.onRetry) {
this.props.onRetry();
}
});
};
render() {
if (this.state.hasError) {
return (
<div>
<h2>åé¡ãçºçããŸããã</h2>
<button onClick={this.handleRetry}>å詊è¡</button>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundaryWithRetry;
ErrorBoundaryWithRetryã³ã³ããŒãã³ãã«ã¯ãã¯ãªãã¯ãããšãhasErrorç¶æ
ããªã»ããããåã³ã³ããŒãã³ããåã¬ã³ããªã³ã°ããå詊è¡ãã¿ã³ãå«ãŸããŠããŸããretryCountã远å ããŠãå詊è¡åæ°ãå¶éããããšãã§ããŸãããã®ã¢ãããŒãã¯ãäžæçãªãããã¯ãŒã¯åæ¢ãªã©ãäžæçãªãšã©ãŒã®åŠçã«ç¹ã«åœ¹ç«ã¡ãŸãã`onRetry`ããããã£ãé©åã«åŠçããããšã©ãŒãçºçããå¯èœæ§ã®ããããžãã¯ãåãã§ãã/åå®è¡ããããšã確èªããŠãã ããã
2. æ©èœãã©ã°
æ©èœãã©ã°ã䜿çšãããšãæ°ããã³ãŒãããããã€ããã«ãã¢ããªã±ãŒã·ã§ã³ã®æ©èœãåçã«æå¹ãŸãã¯ç¡å¹ã«ã§ããŸãããšã©ãŒå¢çãæ©èœãã©ã°ãšçµã¿åãããŠäœ¿çšããŠããšã©ãŒãçºçããå Žåã«æ©èœãåªé ã«äœäžãããããšãã§ããŸããããšãã°ãç¹å®ã®æ©èœããšã©ãŒãåŒãèµ·ãããŠããå Žåã¯ãæ©èœãã©ã°ã䜿çšããŠç¡å¹ã«ããæ©èœãäžæçã«å©çšã§ããªãããšã瀺ãã¡ãã»ãŒãžããŠãŒã¶ãŒã«è¡šç€ºã§ããŸãã
3. ãµãŒããããã¬ãŒã«ãŒãã¿ãŒã³
ãµãŒããããã¬ãŒã«ãŒãã¿ãŒã³ã¯ã倱æããå¯èœæ§ãé«ãæäœãã¢ããªã±ãŒã·ã§ã³ãç¹°ãè¿ãå®è¡ããããšããã®ãé²ãããã«äœ¿çšããããœãããŠã§ã¢èšèšãã¿ãŒã³ã§ããæäœã®æåçãšå€±æçãç£èŠãã倱æçããããããå€ãè¶ ãããšãããµãŒããããéãããäžå®æéæäœã®å®è¡ã詊ã¿ãã®ãé²ããŸããããã«ãããã«ã¹ã±ãŒãé害ãé²ããã¢ããªã±ãŒã·ã§ã³å šäœã®å®å®æ§ãåäžãããããšãã§ããŸãã
ãšã©ãŒå¢çã䜿çšããŠãReactã¢ããªã±ãŒã·ã§ã³ã«ãµãŒããããã¬ãŒã«ãŒãã¿ãŒã³ãå®è£ ã§ããŸãããšã©ãŒå¢çããšã©ãŒããã£ãããããšã倱æã«ãŠã³ã¿ãŒãã€ã³ã¯ãªã¡ã³ãã§ããŸãã倱æã«ãŠã³ã¿ãŒããããå€ãè¶ ãããšããšã©ãŒå¢çã¯ãæ©èœãäžæçã«å©çšã§ããªãããšã瀺ãã¡ãã»ãŒãžããŠãŒã¶ãŒã«è¡šç€ºããæäœã®å®è¡ã詊ã¿ãã®ãé²ãããšãã§ããŸããäžå®æéåŸããšã©ãŒå¢çã¯ããµãŒããããéãããæäœã®å®è¡ãå床詊ã¿ãããšãã§ããŸãã
çµè«
Reactãšã©ãŒå¢çã¯ãå ç¢ã§ãŠãŒã¶ãŒãã¬ã³ããªãŒãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®äžå¯æ¬ ãªããŒã«ã§ãããšã©ãŒå¢çãå®è£ ããããšã«ããããšã©ãŒãã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ãããã®ãé²ãããŠãŒã¶ãŒã«åªé ãªãã©ãŒã«ããã¯UIãæäŸãããšã©ãŒãç£èŠãµãŒãã¹ã«èšé²ããŠãããã°ããã³åæãè¡ãããšãã§ããŸãããã®ã¬ã€ãã§æŠèª¬ãããŠãããã¹ããã©ã¯ãã£ã¹ãšé«åºŠãªæŠç¥ã«åŸãããšã§ãäºæããªããšã©ãŒãçºçããå Žåã§ããå埩åããããä¿¡é Œæ§ãé«ããè¯å®çãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããã°ããŒãã«ãªãŒãã£ãšã³ã¹åãã«ããŒã«ã©ã€ãºããã圹ç«ã€ãšã©ãŒã¡ãã»ãŒãžã³ã°ãæäŸããããšã«çŠç¹ãåœãŠãããšãå¿ããªãã§ãã ããã